﻿using MongoDB.Driver;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.ScreeningTool.Synchronization.Caches;
using System.Collections.Generic;
using System.Linq;
using static Sustainalytics.Utils.ScoreConversion;

namespace Sustainalytics.ScreeningTool.Synchronization.Handlers.ESG
{
    public class EventIndicatorHandler : IHandlerWithGrouping<EventIndicator>
    {
        private readonly ControversyTemplatesCache _controversyTemplatesCache;

        public EventIndicatorHandler(ControversyTemplatesCache controversyTemplatesCache)
        {
            _controversyTemplatesCache = controversyTemplatesCache;
        }

        public ProjectionDefinition<EventIndicator> GetProjection(ProjectionDefinitionBuilder<EventIndicator> builder) => builder
            .Include(x => x.ControversyIndicatorNumber)
            .Include(x => x.ControversyIndicatorName)
            .Include(x => x.ProvidesControversy)
            .Include(x => x.Name)
            .Include(x => x.AnswerCategory)
            .Include(x => x.ControversySummary)
            .Include(x => x.AnswerCategoryJustification)
            .Include(x => x.OutlookText)
            .Include(x => x.OutlookComments)
            .Include(x => x.OutlookScore);

        public IEnumerable<ExtraElement> GetExtraElements(IEnumerable<EventIndicator> entities)
        {
            return EnumerableExtensions.Concat(GetType2ExtraElements(), GetType8ExtraElements());

            IEnumerable<ExtraElement> GetType8ExtraElements()
            {
                var companyId = entities.First().CompanyId;
                var controversyTemplates = _controversyTemplatesCache[companyId];

                return entities
                    .Where(x => x.ProvidesControversy)
                    .Where(x => x.ControversySummary?.Length > 4)
                    .Where(x => controversyTemplates.Contains(x.ControversyIndicatorNumber))
                    .SelectMany(x =>
                    {
                        var key = $"{x.ControversyIndicatorNumber} {x.ControversyIndicatorName}";
                        return new ExtraElementList
                        {
                            { $"{key}-Assessment", x.ControversySummary                       },
                            { $"{key}-Outlook",    GetOutlookAssessment(x.OutlookScore.Value) },
                        };
                    });
            }

            IEnumerable<ExtraElement> GetType2ExtraElements()
                => entities.SelectMany(x => new ExtraElementList
                {
                    { x.Name + "-Answer Category",               x.AnswerCategory              },
                    { x.Name + "-Summary",                       x.GetSummary()                },
                    { x.Name + "-Answer category justification", x.AnswerCategoryJustification },
                    { x.Name + "-Outlook text",                  x.OutlookText                 },
                    { x.Name + "-Outlook comments",              x.GetOutlookComments()        },
                    { x.Name + "-Outlook Score",                 x.OutlookScore                },
                });
        }
    }

    public static class EventIndicatorExtensions
    {
        public static string GetSummary(this EventIndicator eventIndicator)
            => eventIndicator.ControversySummary?.Length > 5 ? eventIndicator.ControversySummary : null;

        public static string GetOutlookComments(this EventIndicator eventIndicator)
            => eventIndicator.OutlookComments.EnsureEndsWithPeriod().JoinStrings(" ");
    }
}
